<?php


namespace Tbf\Bundle\CallbackSerializerBundle\Serializer;


use Tbf\Bundle\CallbackSerializerBundle\CallbackSerializer;
use Tbf\Bundle\CallbackSerializerBundle\Wrapper\CallbackWrapper;
use Tbf\Bundle\SerializerBundle\Handler\ClassNameAwareHandlerInterface;
use Tbf\Bundle\SerializerBundle\Handler\NewFromArray\NewFromArrayInterface;
use Tbf\Bundle\SerializerBundle\Handler\ToArray\ToArrayInterface;
use Tbf\Bundle\SerializerBundle\Serializer;
use Tbf\Bundle\SerializerBundle\SerializerAware;

class CallbackWrapperSerializer extends SerializerAware implements ToArrayInterface,
    NewFromArrayInterface,
    ClassNameAwareHandlerInterface
    {
    protected $app_secret;
    function __construct($app_secret=''){
        $this->app_secret = $app_secret;
    }
    /**
     * @return string
     */
    static function getSerializeClassName()
    {
        return '\Tbf\Bundle\CallbackSerializerBundle\Wrapper\CallbackWrapper';
    }

    public function newFromArray($class_name, $input,$group=null)
    {
        if (!is_string($input)){
            throw new \Exception('CallbackWrapperSerializer:newFromArray input is not a string');
        }
        $pos = strpos($input,':');
        if ($pos===false){
            throw new \Exception('verify fail of a serialized callback');
        }
        $origin_hash = substr($input,0,$pos);
        $origin_value = substr($input,$pos+1);
        $hash = hash('sha256',$this->app_secret.$origin_value.$this->app_secret);
        if ($hash!==$origin_hash){
            return array(null,'verify fail of a serialized callback');
        }
        $value = json_decode($origin_value,true);
        $obj = $this->serializer->newFromArray($value['class'],$value['value']);
        return new CallbackWrapper($obj);
    }

    public function toArray($obj,$group=null)
    {
        /** @var \Tbf\Bundle\CallbackSerializerBundle\Wrapper\CallbackWrapper $obj */
        $callback = $obj->getCallback();
        $origin_value = json_encode(array(
            'class'=>get_class($callback),
            'value'=>$this->serializer->toArray($callback),
        ));
        $hash = hash('sha256',$this->app_secret.$origin_value.$this->app_secret);
        return $hash.':'.$origin_value;
    }

}